<template>
  <div class="screen-container" ref="screenRef">
    <div class="map-wrapper" :style="scaleStyle">
      <div class="title-container">
        <h1 class="main-title">国家就业失业人口统计</h1>
        <div class="title-decoration"></div>
      </div>
      <div ref="mapRef" class="china-map"></div>
      <div class="zoom-controls">
        <button class="zoom-btn" @click="handleZoom('in')">+</button>
        <button class="zoom-btn" @click="handleZoom('out')">-</button>
        <button class="zoom-btn" @click="handleZoom('reset')">↺</button>
      </div>
      <el-drawer
        v-model="sidebarVisible"
        :title="selectedProvince + ' 统计'"
        direction="rtl"
        size="400px"
        :with-header="true"
        :modal="false"
        :show-close="true"
        :before-close="handleClose"
        class="custom-drawer"
      >
        <div ref="echartsRef" style="width: 100%; height: 300px;"></div>
      </el-drawer>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, reactive, watch } from 'vue';
import * as echarts from 'echarts';
import { ElDrawer } from 'element-plus';
import 'element-plus/dist/index.css';
import { provinceStats as mockData } from '../mock.js';

const mapRef = ref(null);
const echartsRef = ref(null);
const screenRef = ref(null);
const sidebarVisible = ref(false);
const selectedProvince = ref('');
const provinceStats = ref([]);
const scaleStyle = ref({});
const currentZoom = ref(1.2);
const minZoom = 0.5;
const maxZoom = 3;

const handleClose = () => {
  sidebarVisible.value = false;
};

const fetchStats = async () => {
  try {
    const res = await fetch('http://localhost:3000/api/provinceStats');
    const result = await res.json();
    
    if (result.code === 200) {
      provinceStats.value = result.data;
    } else {
      console.error('Failed to fetch stats:', result.message);
      // 保留mock数据作为fallback
      provinceStats.value = mockData;
    }
  } catch (error) {
    console.error('Error fetching stats:', error);
    provinceStats.value = mockData;
  }
};

const showSidebar = (province) => {
  selectedProvince.value = province;
  // 如果侧边栏已经打开，直接更新内容
  if (sidebarVisible.value) {
    drawSidebarChart();
  } else {
    // 如果侧边栏未打开，则打开并更新内容
    sidebarVisible.value = true;
    setTimeout(drawSidebarChart, 0);
  }
};

const drawSidebarChart = () => {
  if (!echartsRef.value) return;
  const stat = provinceStats.value.find(p => selectedProvince.value.indexOf(p.name)!='-1');
  if (!stat) return;
  
  // 如果图表实例已存在，先销毁它
  const existingChart = echarts.getInstanceByDom(echartsRef.value);
  if (existingChart) {
    existingChart.dispose();
  }
  
  const chart = echarts.init(echartsRef.value);
  chart.setOption({
    title: { 
      text: `${stat.name} 就业/失业`,
      textStyle: {
        color: '#fff',
        fontSize: 18
      }
    },
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0,0,0,0.7)',
      borderColor: '#00ffff',
      textStyle: {
        color: '#fff'
      }
    },
    grid: {
      top: '15%',
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: { 
      type: 'category', 
      data: ['就业人数', '失业人数', '失业率'],
      axisLine: {
        lineStyle: {
          color: '#00ffff'
        }
      },
      axisLabel: {
        color: '#fff'
      }
    },
    yAxis: {
      type: 'value',
      axisLine: {
        lineStyle: {
          color: '#00ffff'
        }
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(0,255,255,0.1)'
        }
      },
      axisLabel: {
        color: '#fff'
      }
    },
    series: [{
      type: 'bar',
      data: [stat.employed, stat.unemployed, stat.rate],
      itemStyle: { 
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#00ffff' },
          { offset: 1, color: '#0066ff' }
        ])
      },
      animationDelay: function (idx) {
        return idx * 100;
      }
    }]
  });
};

const handleZoom = (type) => {
  let newZoom = currentZoom.value;
  switch (type) {
    case 'in':
      newZoom = Math.min(currentZoom.value + 0.2, maxZoom);
      break;
    case 'out':
      newZoom = Math.max(currentZoom.value - 0.2, minZoom);
      break;
    case 'reset':
      newZoom = 1.2;
      break;
  }
  currentZoom.value = newZoom;
  updateMapZoom();
};

const updateMapZoom = () => {
  const chart = echarts.getInstanceByDom(mapRef.value);
  if (chart) {
    chart.setOption({
      geo: {
        zoom: currentZoom.value
      }
    });
  }
};

const drawMap = () => {
  if (!mapRef.value) return;
  const myChart = echarts.init(mapRef.value);
  
  // 拉取中国地图 GeoJSON 数据
  fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json')
    .then(response => response.json())
    .then(geoJson => {
      // 注册地图数据
      echarts.registerMap('china', geoJson);
      // 计算所有省份失业率的最大值和最小值，用于 visualMap 颜色映射
      const rates = provinceStats.value.map(p => p.rate);
      const maxRate = Math.max(...rates);
      const minRate = Math.min(...rates);
      
      // 构造地图主数据，name 为省份名，value 为失业率
      const mapData = provinceStats.value.map(item => ({
        name: item.name,
        value: item.rate
      }));

      // 配置 ECharts 选项
      const option = {
        // 鼠标悬浮提示框
        tooltip: { 
          trigger: 'item',
          formatter: function(params) {
            // 查找当前省份的详细数据
            const province = provinceStats.value.find(p => params.name.indexOf(p.name)!='-1');
            if (province) {
              return `${params.name}<br/>
                      就业人数：${province.employed}万人<br/>
                      失业人数：${province.unemployed}万人<br/>
                      失业率：${province.rate}%`;
            }
            return params.name;
          },
          backgroundColor: 'rgba(0,0,0,0.7)',
          borderColor: '#00ffff',
          textStyle: {
            color: '#fff',
          }
        },
        // 视觉映射组件，控制地图主色带
        visualMap: {
          type: 'continuous',
          min: minRate,
          max: maxRate,
          text: ['高', '低'],
          realtime: false,
          calculable: true,
          inRange: {
            color: ['#50a3ba', '#eac736', '#d94e5d'] // 低-中-高失业率颜色
          },
          textStyle: {
            color: '#fff'
          },
          left: 'left',
          top: 'bottom',
          orient: 'horizontal',
          padding: [5, 10],
          backgroundColor: 'rgba(0,0,0,0.3)',
          borderColor: '#00ffff',
          borderWidth: 1
        },
        // 地理坐标系配置
        geo: {
          map: 'china',
          roam: true, // 允许缩放和拖拽
          center: [104.5, 36.5],
          zoom: currentZoom.value,
          label: { show: false },
          itemStyle: {
            areaColor: '#0c2743',
            borderColor: '#1cccff',
            borderWidth: 1.5,
            shadowColor: 'rgba(0, 255, 255, 0.5)',
            shadowBlur: 10
          },
          emphasis: {
            label: { show: false },
            itemStyle: { areaColor: '#0a2dae' }
          }
        },
        series: [
          // 主地图系列
          {
            name: '失业率',
            type: 'map',
            map: 'china',
            geoIndex: 0,
            roam: true,
            center: [104.5, 36.5],
            zoom: currentZoom.value,
            data: mapData,
            label: {
              show: true,
              formatter: '{b}',
              fontSize: 8,
              color: '#fff'
            },
            itemStyle: {
              areaColor: '#0c2743',
              borderColor: '#1cccff',
              borderWidth: 1.5,
              shadowColor: 'rgba(0, 255, 255, 0.5)',
              shadowBlur: 10
            },
            emphasis: {
              label: { 
                show: true,
                fontSize: 12,
                color: '#fff',
                fontWeight: 'bold'
              },
              itemStyle: { 
                areaColor: '#0a2dae',
                shadowColor: '#00ffff',
                shadowBlur: 20
              }
            }
          },
          // 高失业率省份的涟漪点系列
          {
            type: 'effectScatter',
            coordinateSystem: 'geo',
            geoIndex: 0,
            // 只显示失业率大于8%的省份
            data: provinceStats.value
              .filter(p => p.rate > 8)
              .map(p => {
                const center = getProvinceCenter(p.name); // 获取省份中心坐标
                return {
                  name: p.name,
                  value: [center[0], center[1], p.rate], // [经度, 纬度, 失业率]
                  symbolSize: 15, // 点的大小
                  itemStyle: {
                    color: '#ff4444' // TODO: 可改为动态颜色
                  }
                };
              }),
            rippleEffect: {
              brushType: 'stroke',
              scale: 3,
              period: 3,
              color: '#ff4444'
            },
            zlevel: 1,
            hoverAnimation: true,
            label: {
              show: true,
              position: 'right',
              formatter: '{b}',
              color: '#fff'
            }
          }
        ]
      };

      // 设置地图配置项
      myChart.setOption(option);
      
      // 添加鼠标滚轮缩放事件，联动自定义缩放按钮
      myChart.getZr().on('mousewheel', (params) => {
        const delta = params.event.deltaY;
        if (delta > 0) {
          handleZoom('out');
        } else {
          handleZoom('in');
        }
      });
    })
    .catch(error => {
      console.error('Failed to load map data:', error);
    });

  // 地图点击事件，显示省份详细数据侧边栏
  myChart.on('click', params => {
    if (params.name) showSidebar(params.name);
  });
};

// 获取省份中心点坐标
const getProvinceCenter = (provinceName) => {
  const centers = {
    '北京': [116.46, 39.92],
    '上海': [121.48, 31.22],
    '广东': [113.23, 23.16],
    '四川': [104.06, 30.67],
    '江苏': [118.78, 32.04],
    '浙江': [120.19, 30.26],
    '山东': [117.00, 36.65],
    '河南': [113.65, 34.76],
    '湖北': [114.31, 30.52],
    '湖南': [112.94, 28.23],
    '河北': [114.52, 38.04],
    '福建': [119.30, 26.08],
    '安徽': [117.27, 31.86],
    '江西': [115.89, 28.68],
    '广西': [108.33, 22.84],
    '海南': [110.35, 20.02],
    '重庆': [106.54, 29.59],
    '贵州': [106.71, 26.57],
    '云南': [102.73, 25.04],
    '西藏': [91.11, 29.97],
    '陕西': [108.95, 34.27],
    '甘肃': [103.73, 36.03],
    '青海': [101.74, 36.56],
    '宁夏': [106.27, 38.47],
    '新疆': [87.68, 43.77],
    '内蒙古': [111.65, 40.82],
    '辽宁': [123.38, 41.80],
    '吉林': [125.35, 43.88],
    '黑龙江': [126.63, 45.75],
    '山西': [112.53, 37.87],
    '天津': [117.20, 39.13]
  };
  return centers[provinceName] || [0, 0];
};

const resizeScreen = () => {
  const baseWidth = 1920;
  const baseHeight = 1080;
  const w = window.innerWidth;
  const h = window.innerHeight;
  const scale = Math.min(w / baseWidth, h / baseHeight);
  scaleStyle.value = {
    transform: `scale(${scale})`,
    transformOrigin: 'center center',
    width: baseWidth + 'px',
    height: baseHeight + 'px',
    position: 'absolute',
    left: '50%',
    top: '50%',
    marginLeft: `-${baseWidth/2}px`,
    marginTop: `-${baseHeight/2}px`,
    background: 'linear-gradient(to bottom, #000b1e, #001233)',
    overflow: 'hidden',
  };
};

onMounted(async () => {
  await fetchStats();
  drawMap();
  resizeScreen();
  window.addEventListener('resize', resizeScreen);
});
</script>

<style scoped>
.screen-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: linear-gradient(to bottom, #000b1e, #001233);
  position: relative;
}

.screen-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: 
    linear-gradient(90deg, rgba(0,255,255,0.05) 1px, transparent 1px) 0 0 / 50px 50px,
    linear-gradient(rgba(0,255,255,0.05) 1px, transparent 1px) 0 0 / 50px 50px;
  pointer-events: none;
  animation: gridMove 20s linear infinite;
}

.map-wrapper {
  width: 1920px;
  height: 1080px;
  position: relative;
}

.china-map {
  width: 100%;
  height: 100%;
  /* background: rgba(0, 18, 51, 0.8); */
  border-radius: 16px;
  box-shadow: 0 0 30px rgba(0, 255, 255, 0.2);
  border: 1px solid rgba(0, 255, 255, 0.3);
  backdrop-filter: blur(10px);
  transition: all 0.3s ease;
}

.china-map:hover {
  box-shadow: 0 0 40px rgba(0, 255, 255, 0.3);
}

:deep(.custom-drawer) {
  background: rgba(0, 18, 51, 0.9) !important;
  backdrop-filter: blur(10px);
  border-left: 1px solid rgba(0, 255, 255, 0.3);
}

:deep(.custom-drawer .el-drawer__header) {
  color: #fff;
  margin-bottom: 0;
  padding: 20px;
  border-bottom: 1px solid rgba(0, 255, 255, 0.3);
}

:deep(.custom-drawer .el-drawer__body) {
  padding: 20px;
}

:deep(.custom-drawer .el-drawer__close) {
  color: #fff;
}

:deep(.custom-drawer .el-drawer__close:hover) {
  color: #00ffff;
}

@keyframes gridMove {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(50px);
  }
}

@keyframes buttonShine {
  0% {
    transform: translateX(-100%) rotate(45deg);
  }
  100% {
    transform: translateX(100%) rotate(45deg);
  }
}

@keyframes dataFlow {
  0% {
    stroke-dashoffset: 1000;
  }
  100% {
    stroke-dashoffset: 0;
  }
}

@keyframes breathe {
  0%, 100% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
  }
}

.zoom-controls {
  position: absolute;
  right: 20px;
  top: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 100;
}

.zoom-btn {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1px solid rgba(0, 255, 255, 0.3);
  background: rgba(0, 18, 51, 0.8);
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.zoom-btn:hover {
  background: rgba(0, 255, 255, 0.2);
  border-color: #00ffff;
  box-shadow: 0 0 15px rgba(0, 255, 255, 0.3);
}

.zoom-btn:active {
  transform: scale(0.95);
}

.title-container {
  position: absolute;
  top: 40px;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  z-index: 100;
}

.main-title {
  font-size: 36px;
  color: #fff;
  text-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
  margin: 0;
  padding: 0;
  font-weight: 500;
  letter-spacing: 2px;
  background: linear-gradient(to right, #fff, #00ffff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  position: relative;
}

.title-decoration {
  position: absolute;
  bottom: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 200px;
  height: 2px;
  background: linear-gradient(to right, transparent, #00ffff, transparent);
  box-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
}

.title-decoration::before,
.title-decoration::after {
  content: '';
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #00ffff;
  box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
  top: 50%;
  transform: translateY(-50%);
}

.title-decoration::before {
  left: 0;
}

.title-decoration::after {
  right: 0;
}
</style>